C.S.Burner 🪙 ━►🔥GIT Node
Node / reticulum_mirror / MeshChatX / files / meshchatx / src / frontend / components / interfaces / ImportInterfacesModal.vue
Displaying Raw • Download
meshchatx/src/frontend/components/interfaces/ImportInterfacesModal.vue 67e78aa299d1bde9de61fcc4dc3e95a36eeb92d6 (67e78aa2) Text, 12.65 KB
T8b949e<!-- SPDX-License-Identifier: 0BSD AND MIT -->
Tff7b72<templateTff7b72>
Tff7b72<div
Te6edf3v-if=Ta5d6ff"Ta5d6ffisShowingTa5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6fffixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity flex items-center justify-centerTa5d6ff"
Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffflex w-full h-full p-4 overflow-y-autoTa5d6ff"Tff7b72>
Tff7b72<div
Te6edf3v-click-outside=Ta5d6ff"Ta5d6ffdismissTa5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6ffmy-auto mx-auto w-full bg-white dark:bg-zinc-900 rounded-lg shadow-xl max-w-2xlTa5d6ff"
Tff7b72>
T8b949e<!-- title -->
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffp-4 border-b dark:border-zinc-700Ta5d6ff"Tff7b72>
Tff7b72<h3 Te6edf3class=Ta5d6ff"Ta5d6fftext-lg font-semibold dark:text-whiteTa5d6ff"Tff7b72>Import InterfacesTff7b72</h3>
Tff7b72</div>
T8b949e<!-- content -->
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffdivide-y dark:divide-zinc-700Ta5d6ff"Tff7b72>
T8b949e<!-- file input -->
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffp-2Ta5d6ff"Tff7b72>
Tff7b72<divTff7b72>
Tff7b72<input
Te6edf3ref=Ta5d6ff"Ta5d6ffimport-interfaces-file-inputTa5d6ff"
Te6edf3type=Ta5d6ff"Ta5d6fffileTa5d6ff"
Te6edf3accept=Ta5d6ff"Ta5d6ff*Ta5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6ffw-full text-sm text-gray-500 dark:text-zinc-400Ta5d6ff"
@Te6edf3change=Ta5d6ff"Ta5d6ffonFileSelectedTa5d6ff"
Tff7b72/>
Tff7b72</div>
Tff7b72<div Te6edf3v-if=Ta5d6ff"Ta5d6ff!selectedFileTa5d6ff" Te6edf3class=Ta5d6ff"Ta5d6ffmt-2 text-sm text-gray-700 dark:text-zinc-200Ta5d6ff"Tff7b72>
Tff7b72<ul Te6edf3class=Ta5d6ff"Ta5d6fflist-disc list-insideTa5d6ff"Tff7b72>
Tff7b72<liTff7b72>You can import interfaces from a ~/.reticulum/config file.Tff7b72</li>
Tff7b72<liTff7b72>You can import interfaces from an exported interfaces file.Tff7b72</li>
Tff7b72<liTff7b72>{{ Te6edf3$t("interfaces.i2p_import_forbidden") }}Tff7b72</li>
Tff7b72</ul>
Tff7b72</div>
Tff7b72</div>
T8b949e<!-- select interfaces -->
Tff7b72<div Te6edf3v-if=Ta5d6ff"Ta5d6ffimportableInterfaces.length > 0Ta5d6ff" Te6edf3class=Ta5d6ff"Ta5d6ffdivide-y dark:divide-zinc-700Ta5d6ff"Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffflex p-2Ta5d6ff"Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffmy-auto mr-auto text-sm font-medium text-gray-700 dark:text-zinc-200Ta5d6ff"Tff7b72>
Select Interfaces to Import
Tff7b72</div>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffmy-auto space-x-2Ta5d6ff"Tff7b72>
Tff7b72<button Te6edf3class=Ta5d6ff"Ta5d6fftext-sm text-blue-500 hover:underlineTa5d6ff" @Te6edf3click=Ta5d6ff"Ta5d6ffselectAllInterfacesTa5d6ff"Tff7b72>
Select All
Tff7b72</button>
Tff7b72<button Te6edf3class=Ta5d6ff"Ta5d6fftext-sm text-blue-500 hover:underlineTa5d6ff" @Te6edf3click=Ta5d6ff"Ta5d6ffdeselectAllInterfacesTa5d6ff"Tff7b72>
Deselect All
Tff7b72</button>
Tff7b72</div>
Tff7b72</div>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffbg-gray-200 p-2 space-y-2 max-h-80 overflow-y-auto dark:bg-zinc-800Ta5d6ff"Tff7b72>
Tff7b72<div
Te6edf3v-for=Ta5d6ff"Ta5d6ffiface in importableInterfacesTa5d6ff"
Te6edf3:key=Ta5d6ff"Ta5d6ffiface.nameTa5d6ff"
Te6edf3class=Ta5d6ff"Ta5d6ffbg-white cursor-pointer flex items-center p-2 border rounded-sm shadow-sm dark:bg-zinc-900 dark:border-zinc-700Ta5d6ff"
Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffmr-auto text-sm flex-1Ta5d6ff" @Te6edf3click=Ta5d6ff"Ta5d6fftoggleSelectedInterface(iface.name)Ta5d6ff"Tff7b72>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6fffont-semibold text-gray-700 dark:text-zinc-100Ta5d6ff"Tff7b72>{{ iface.name }}Tff7b72</div>
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6fftext-sm text-gray-500 dark:text-zinc-100Ta5d6ff"Tff7b72>
T8b949e<!-- auto interface -->
Tff7b72<div Te6edf3v-if=Ta5d6ff"Ta5d6ffiface.type === Ta5d6ff'Ta5d6ffAutoInterfaceTa5d6ff'Ta5d6ff"Tff7b72>
Tff7b72<divTff7b72>{{ iface.type }}Tff7b72</div>
Tff7b72<divTff7b72>Ethernet and WiFiTff7b72</div>
Tff7b72</div>
T8b949e<!-- tcp client interface -->
Tff7b72<div Te6edf3v-else-if=Ta5d6ff"Ta5d6ffiface.type === Ta5d6ff'Ta5d6ffTCPClientInterfaceTa5d6ff'Ta5d6ff"Tff7b72>
Tff7b72<divTff7b72>{{ iface.type }}Tff7b72</div>
Tff7b72<divTff7b72>{{ iface.target_host }}:{{ iface.target_port }}Tff7b72</div>
Tff7b72</div>
T8b949e<!-- tcp server interface -->
Tff7b72<div Te6edf3v-else-if=Ta5d6ff"Ta5d6ffiface.type === Ta5d6ff'Ta5d6ffTCPServerInterfaceTa5d6ff'Ta5d6ff"Tff7b72>
Tff7b72<divTff7b72>{{ iface.type }}Tff7b72</div>
Tff7b72<divTff7b72>{{ iface.listen_ip }}:{{ iface.listen_port }}Tff7b72</div>
Tff7b72</div>
T8b949e<!-- udp interface -->
Tff7b72<div Te6edf3v-else-if=Ta5d6ff"Ta5d6ffiface.type === Ta5d6ff'Ta5d6ffUDPInterfaceTa5d6ff'Ta5d6ff"Tff7b72>
Tff7b72<divTff7b72>{{ iface.type }}Tff7b72</div>
Tff7b72<divTff7b72>Listen: {{ iface.listen_ip }}:{{ iface.listen_port }}Tff7b72</div>
Tff7b72<divTff7b72>Forward: {{ iface.forward_ip }}:{{ iface.forward_port }}Tff7b72</div>
Tff7b72</div>
T8b949e<!-- rnode interface details -->
Tff7b72<div Te6edf3v-else-if=Ta5d6ff"Ta5d6ffiface.type === Ta5d6ff'Ta5d6ffRNodeInterfaceTa5d6ff'Ta5d6ff"Tff7b72>
Tff7b72<divTff7b72>{{ iface.type }}Tff7b72</div>
Tff7b72<divTff7b72>Port: {{ iface.port }}Tff7b72</div>
Tff7b72<divTff7b72>Frequency: {{ formatFrequency(iface.frequency) }}Tff7b72</div>
Tff7b72<divTff7b72>Bandwidth: {{ formatFrequency(iface.bandwidth) }}Tff7b72</div>
Tff7b72<divTff7b72>Spreading Factor: {{ iface.spreadingfactor }}Tff7b72</div>
Tff7b72<divTff7b72>Coding Rate: {{ iface.codingrate }}Tff7b72</div>
Tff7b72<divTff7b72>Transmit Power: {{ iface.txpower }}dBmTff7b72</div>
Tff7b72</div>
T8b949e<!-- other interface types -->
Tff7b72<div v-elseTff7b72>{{ iface.type }}Tff7b72</div>
Tff7b72</div>
Tff7b72</div>
Tff7b72<div @click.stopTff7b72>
Tff7b72<Toggle
Te6edf3:id=Ta5d6ff"Ta5d6ff`import-interface-Tff7b72${Te6edf3ifaceTff7b72.Td2a8ffnameTff7b72}Ta5d6ff`Ta5d6ff"
Te6edf3:model-value=Ta5d6ff"Ta5d6ffselectedInterfaces.includes(iface.name)Ta5d6ff"
@Te6edf3update:model-value=Ta5d6ff"
Ta5d6ff (value) => {
if (value && !selectedInterfaces.includes(iface.name))
selectInterface(iface.name);
else if (!value && selectedInterfaces.includes(iface.name))
deselectInterface(iface.name);
}
Ta5d6ff"
Tff7b72/>
Tff7b72</div>
Tff7b72</div>
Tff7b72</div>
Tff7b72</div>
Tff7b72</div>
T8b949e<!-- actions -->
Tff7b72<div Te6edf3class=Ta5d6ff"Ta5d6ffp-4 border-t dark:border-zinc-700 flex justify-end space-x-2Ta5d6ff"Tff7b72>
Tff7b72<button
Te6edf3class=Ta5d6ff"Ta5d6ffpx-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 dark:bg-zinc-800 dark:text-zinc-200 dark:border-zinc-600 dark:hover:bg-zinc-700Ta5d6ff"
@Te6edf3click=Ta5d6ff"Ta5d6ffdismissTa5d6ff"
Tff7b72>
Cancel
Tff7b72</button>
Tff7b72<button
Te6edf3class=Ta5d6ff"Ta5d6ffpx-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 dark:bg-blue-700 dark:hover:bg-blue-600Ta5d6ff"
@Te6edf3click=Ta5d6ff"Ta5d6ffimportSelectedInterfacesTa5d6ff"
Tff7b72>
Import Selected
Tff7b72</button>
Tff7b72</div>
Tff7b72</div>
Tff7b72</div>
Tff7b72</div>
Tff7b72</template>
Tff7b72<scriptTff7b72>
import DialogUtils from "../../js/DialogUtils";
import Utils from "../../js/Utils";
import Toggle from "../forms/Toggle.vue";
export default {
name: "ImportInterfacesModal",
components: {
Toggle,
},
emits: ["dismissed"],
data() {
return {
isShowing: false,
selectedFile: null,
importableInterfaces: [],
selectedInterfaces: [],
};
},
methods: {
show() {
this.isShowing = true;
this.selectedFile = null;
this.importableInterfaces = [];
this.selectedInterfaces = [];
},
dismiss(result = false) {
this.isShowing = false;
const imported = result === true;
this.$emit("dismissed", imported);
},
clearSelectedFile() {
this.selectedFile = null;
this.$refs["import-interfaces-file-input"].value = null;
},
async onFileSelected(event) {
// get selected file
const file = event.target.files[0];
if (!file) {
return;
}
// update ui
this.selectedFile = file;
this.importableInterfaces = [];
this.selectedInterfaces = [];
try {
// fetch preview of interfaces to import
const response = await window.api.post("/api/v1/reticulum/interfaces/import-preview", {
config: await file.text(),
});
// ensure there are some interfaces available to import
if (!response.data.interfaces || response.data.interfaces.length === 0) {
this.clearSelectedFile();
DialogUtils.alert(this.$t("interfaces.no_interfaces_found_config"));
return;
}
// update ui
this.importableInterfaces = response.data.interfaces;
// auto select all interfaces
this.selectAllInterfaces();
} catch (e) {
this.clearSelectedFile();
DialogUtils.alert(this.$t("interfaces.failed_parse_config"));
console.error(e);
}
},
isInterfaceSelected(name) {
return this.selectedInterfaces.includes(name);
},
selectInterface(name) {
if (!this.isInterfaceSelected(name)) {
this.selectedInterfaces.push(name);
}
},
deselectInterface(name) {
this.selectedInterfaces = this.selectedInterfaces.filter((selectedInterfaceName) => {
return selectedInterfaceName !== name;
});
},
toggleSelectedInterface(name) {
if (this.isInterfaceSelected(name)) {
this.deselectInterface(name);
} else {
this.selectInterface(name);
}
},
selectAllInterfaces() {
this.selectedInterfaces = this.importableInterfaces.map((i) => i.name);
},
deselectAllInterfaces() {
this.selectedInterfaces = [];
},
async importSelectedInterfaces() {
// ensure user selected a file to import from
if (!this.selectedFile) {
DialogUtils.alert(this.$t("interfaces.select_config_file"));
return;
}
// ensure user selected some interfaces
if (this.selectedInterfaces.length === 0) {
DialogUtils.alert(this.$t("interfaces.select_at_least_one"));
return;
}
try {
// import interfaces
await window.api.post("/api/v1/reticulum/interfaces/import", {
config: await this.selectedFile.text(),
selected_interface_names: this.selectedInterfaces,
});
// dismiss modal
this.dismiss(true);
// tell user interfaces were imported
DialogUtils.alert(this.$t("interfaces.import_success"));
} catch (e) {
const message = e.response?.data?.message || this.$t("interfaces.failed_import_all");
DialogUtils.alert(message);
console.error(e);
}
},
formatFrequency(hz) {
return Utils.formatFrequency(hz);
},
},
};
Tff7b72</script>
Served by rngit 1.5.2 - Generated in 0.04s